LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY portmap IS
      PORT ( Clock 		: 	IN      STD_LOGIC ;
			 FrameRB	: 	IN      STD_LOGIC ;
			 Bcast		:	IN		STD_LOGIC ;
			
			 Ptr		: 	IN	  	STD_LOGIC_VECTOR (7 DOWNTO 0) ;
             MacDest	: 	IN     	STD_LOGIC_VECTOR (7 DOWNTO 0) ;
			 MacSrc 	: 	IN 	  	STD_LOGIC_VECTOR (7 DOWNTO 0) ;
			 PortDestin :	IN		STD_LOGIC_VECTOR (1 DOWNTO 0) ;	
					
			 MD			: 	BUFFER  STD_LOGIC_VECTOR (7 DOWNTO 0) ;
			 MS			: 	BUFFER  STD_LOGIC_VECTOR (7 DOWNTO 0) ;
			 P			: 	BUFFER  STD_LOGIC_VECTOR (7 DOWNTO 0) ;
			 PD			: 	BUFFER  STD_LOGIC_VECTOR (1 DOWNTO 0) ;
			 PS			: 	BUFFER  STD_LOGIC_VECTOR (1 DOWNTO 0) ;
			
			 BC			:	BUFFER  STD_LOGIC ;
			 ACKRCV		:	BUFFER  STD_LOGIC ;
			 ACKRDY		:	BUFFER  STD_LOGIC ;

			 PortDest	: 	OUT 	STD_LOGIC_VECTOR (1 DOWNTO 0) ;
			 PortSrc	: 	OUT 	STD_LOGIC_VECTOR (1 DOWNTO 0) ;
			
			 Busy		:	OUT 	STD_LOGIC ; 
			 Bcastack  	:	OUT		STD_LOGIC 
			);
CONSTANT Init : STD_LOGIC_VECTOR (7 DOWNTO 0) := "00000000";			
END portmap;

ARCHITECTURE Behavior OF portmap IS
	TYPE State_type IS (NEWFRAME,RCVINFO,TOLUT,TOFABRIC,FIN);
	SIGNAL y : State_type ;
	
BEGIN
	PROCESS (FrameRB, Clock)
	BEGIN
	-- Initialize the buffers
		IF FrameRB = '0' THEN
			MD 			<= Init;
			MS 			<= Init;
			P 			<= Init;
			Busy		<= '0';
			BC			<= '0';
			ACKRCV		<= '0';
			ACKRDY		<= '0';
			PD			<= "00";
			PS			<= "00";
			y 			<= NEWFRAME;
		ELSIF (Clock'EVENT AND Clock = '1') THEN
			CASE y IS
			
				WHEN NEWFRAME =>
					IF FrameRB = '1' THEN
						Busy 	<= '1';
						ACKRCV 	<= '1';
						y <= RCVINFO;
					ELSE
						y <= NEWFRAME;
					END IF;
					
				WHEN RCVINFO =>
					IF ACKRCV = '1' THEN	
					-- Port mapping hard coded for testing here
						IF MacSrc = "01001001" THEN
							PS <= "01";
							ELSIF MacSrc = "00100100" THEN
								PS <= "10";
							ELSIF MacSrc = "01010101" THEN
								PS <= "11";
							ELSE 
								PS <= "00";
						END IF;		
						-- Buffers store info	
						MD 	<= MacDest;
						MS 	<= MacSrc;							
						P 	<= Ptr;	
						-- Block signals it's ready for LUT XMT
						ACKRCV 	<= '0';
						ACKRDY 	<= '1';
						
						y <= TOLUT;
					ELSE
						y <= RCVINFO;
					END IF;
					
				WHEN TOLUT =>
					IF ACKRDY = '1' THEN	
						BC	 		<= Bcast;
						PD 			<= PortDestin;
						ACKRDY 		<= '0';
						ACKRCV 		<= '1';
						y <= TOFABRIC;
					ELSE
						y <= TOLUT;
					END IF;
				
				WHEN TOFABRIC =>
					IF (ACKRCV = '1' AND BC = '0') THEN
						PortDest 	<= PortDestin;
						PortSrc 	<= PS;
						Bcastack	<= BC;
						ACKRCV 		<= '0';
						ACKRDY		<= '1';
						y <= FIN;
						ELSIF (ACKRCV = '1' AND BC = '1') THEN
						PortDest	<= "00";
						PortSrc		<= PS;
						Bcastack 	<= BC;
						ACKRCV 		<= '0';
						ACKRDY 		<= '1';
					ELSE
						y <= TOFABRIC;
					END IF;	
					
				WHEN FIN =>
				    IF ACKRCV = '0' THEN
						MD 			<= Init;
						MS 			<= Init;
						P 			<= Init;
						Busy		<= '0';
						BC			<= '0';
						Bcastack	<= '0';
						ACKRCV 		<= '1';
						ACKRDY		<= '1';
						y 			<= NEWFRAME;
					ELSE
						y <= FIN;
					END IF;
			END CASE;
		END IF ;
	END PROCESS ;
END Behavior ;